    \section{M\'odulo Multiconjunto Acotado de Naturales}
El m\'odulo multiconjunto acotado de naturales provee un multiconjunto en el que se pueden insertar \'unicamente los elementos que se 
encuentran por debajo de una cota natural $cota$. La inserci\'on y borrado y el testeo de pertenencia de un multiconjunto se pueden resolver 
en tiempo logar\'itmico respecto de la cantidad de elementos distintos en el conjunto. Tambi\'en es posible obtener un conjunto acotado de naturales
con los elementos sin repetir del multiconjunto en \complejidad{$O$}{1}.\\
Por \'ultimo, el m\'odulo permite consultar cu\'al es el elemento con la menor cantidad de apariciones en tiempo logar\'itmico respecto de la
cantidad de elementos distintos.

	\subsection{Interfaz}
	  \begin{interfaces}{MultConjAcotado}{}{}{}{Multiconjunto(nat), Multiconjunto Extendido(nat)}{multconjAcotado}
	   \interfaz{MultiConjAcotadoVacio}{\parametro{in}{cota}{nat}}{multconjAcotado}
	      {$cota > 0$}
	      {$res \igobs \emptyset$}
	      {\complejidad{$O$}{$cota$}}{}
	      {}
	      {Crea un multiconjunto acotado de naturales vac\'io al cual se le pueden agregar n\'umeros menores a la cota.}

	   \interfaz{Agregar}{\parametro{in/out}{m}{multconjAcotado}, \parametro{in}{elemento}{nat}, \parametro{in}{cantidad}{nat}}{}
	      {$m_0 \igobs m \land elemento < m.cota$}
	      {$m \igobs m_0 \cup$ Reps($elemento, cantidad$)}
	      {\complejidad{$O$}{$\log(n)$}}{donde n es la cantidad de elementos distintos del multiconjunto $m$.}
	      {}
	      {Agrega al conjunto $m$ el elemento $elemento$ $cantidad$ veces.}

	   \interfaz{Quitar}{\parametro{in/out}{m}{multconjAcotado}, \parametro{in}{elemento}{nat}, \parametro{in}{cantidad}{nat}}{}
	      {$m_0 \igobs m$}
	      {$m \igobs m_0 -$ Reps($elemento, cantidad$)}
	      {\complejidad{$O$}{$\log(n)$}}{donde n es la cantidad de elementos distintos del multiconjunto $m$.}
	      {}
	      {Quita de $m$ el elemento $elemento$ $cantidad$ veces.}

	   \interfaz{Pertenece}{\parametro{in}{m}{multconjAcotado}, \parametro{in}{elemento}{nat}}{bool}
	      {true}
	      {$res \igobs elemento \in m$}
	      {\complejidad{$\Theta$}{$1$}}{}
	      {}
	      {Devuelve true si el elemento pertenece al multiconjunto.}

	   \interfaz{Cardinal}{\parametro{in}{m}{multconjAcotado}}{nat}
	      {true}
	      {$res \igobs \text{\#}m$}
	      {\complejidad{$\Theta$}{1}}{}
	      {}
	      {Devuelve la cantidad de elementos del multiconjunto.}

	   \interfaz{M\'inimo}{\parametro{in}{m}{multconjAcotado}}{nat}
	      {$\lnot \emptyset?(m)$}
	      {$res \igobs$ DameUno(minAps($m$))}
	      {\complejidad{$\Theta$}{$1$}}{}
	      {}
	      {Devuelve el elemento de menor cantidad de apariciones en el multiconjunto. En caso de que no sea \'unico se devuelve el que tenga mayor valor (ya que son naturales).}

	   \interfaz{Conj}{\parametro{in}{m}{multconjAcotado}}{conjAcotado(nat)}
	      {true}
	      {$res \igobs$ Conj($m$)}
	      {\complejidad{$\Theta$}{$1$}}{}
	      {}
	      {Devuelve el conjunto del multiconjunto (sin repeticiones de elementos).}

	   \interfaz{CantDistintos}{\parametro{in}{m}{multconjAcotado}}{nat}
	      {true}
	      {$res \igobs$ \#Conj($m$)}
	      {\complejidad{$\Theta$}{$1$}}{}
	      {}
	      {Devuelve la cantidad de elementos del conjunto equivalente, sin repeticiones de elementos.}
	  \end{interfaces}

    \subsection{Operaciones auxiliares no exportadas}
    Las siguientes operaciones fueron extraidas de los algoritmos para mejorar la lectura de los mismos. 
    La mayor\'ia parte de un estado en el que el invariante de representaci\'on no se cumple y se encargan de reestablecerlos, 
    otras, simplemente tienen como objetivo mejorar la sem\'antica del pseudoc\'odigo.

    \interfaz{EliminarRaiz}{\parametro{in/out}{m}{multconjAcotado}}{}
	{}
	{}
	{\complejidad{O}{$\log(n)$}}{donde n es la cantidad de elementos en el heap.}
	{}
	{Elimina el elemento de la raiz del heap.}


    \interfaz{Subir}{\parametro{in/out}{m}{multconjAcotado}, \parametro{in}{pos}{nat}}{}
	{}
	{}
	{\complejidad{O}{$\log(pos)$}}{donde pos es la posici\'on del elemento del heap que se va a subir.}
	{}
	{Subir el elemento de la posici\'on $pos$ hasta reestablecer el invariante de representaci\'on.}

    \interfaz{Prioridad}{\parametro{in}{m}{multconjAcotado}, \parametro{in}{elemento}{nat}}{}
	{}
	{}
	{\complejidad{$\Theta$}{1}}{}
	{}
	{Calcula la prioridad del elemento.}

    \interfaz{Padre}{\parametro{in}{m}{multconjAcotado}, \parametro{in}{i}{nat}}{}
	{}
	{}
	{\complejidad{$\Theta$}{1}}{}
	{}
	{Calcula el padre de $i$.}

    \interfaz{Bajar}{\parametro{in/out}{m}{multconjAcotado}, \parametro{in}{pos}{nat}}{}
	{}
	{}
	{\complejidad{$O$}{$\log(pos)$}}{donde pos es la posici\'on del elemento del heap que se va a bajar.}
	{}
	{Bajar el elemento de la posici\'on $pos$ hasta reestablecer el invariante de representaci\'on.}

	\subsection{Representaci\'on}
% 	   m es <
% 	repeticiones: ArrayDimensionable(nat),
% 	posiciones: ArrayDimensionable(nat),
% 	heap: ArrayDimensionable(nat),
% 	cota: nat,
% 	pos_libre:nat,
% 	cardinal: nat,
% 	elementos: conjAcotado
% >
La representaci\'on utilizada se basa en tres arreglos dimensionables que contienen la informaci\'on del multiconjunto y permiten devolver el m\'inimo en 
\complejidad{$O$}{$\log(n)$}, siendo $n$ la cantidad de elementos distintos presentes en el multiconjunto. \\
El arreglo $repeticiones$ contiene la cantidad de apariciones de cada elemento del multiconjunto. El arreglo $heap$, contiene una estructura
minHeap que permite devolver el elemento con menor cantidad de apariciones satisfaciendo la compljidad requerida. Cada elemento del Heap es un \'indice
del arreglo $repeticiones$. \\
Para poder satisfacer la complejidad de \proc{M\'inimo}, se agrega el arreglo $posiciones$, que contiene los \'indices para cada elemento 
del multiconjunto en el heap. En el caso de que un elemento $i$ no perteneciera al multiconjunto, su valor en $repeticiones[i]$ ser\'a 0 y $posiciones[i]$ 
ser\'a igual a la cota del multiconjunto.
Para completar la representaci\'on satisfaciendo las complejidades \complejidad{$O$}{1} de algunas operaciones se agrega la $cota$ pasada
al crear el multiconjunto, el cardinal del conjunto y un conjunto convencional con los elementos que pertenecen al multiconjunto.\\

	\representacion{multconjAcotado}{se representa con}{estM}, donde \representacion{estM}{es}{}
	\begin{definicionTupla}
		    \elementoTupla{repeticiones}{arreglo\_dimensionable(nat)},\\
		    \elementoTupla{posiciones}{arreglo\_dimensionable(nat)},\\
		    \elementoTupla{heap}{arreglo\_dimensionable(nat)},\\
		    \elementoTupla{cota}{nat},\\
		    \elementoTupla{pos\_libre}{nat},\\
		    \elementoTupla{cardinal}{nat},\\
		    \elementoTupla{elementos}{conjAcotado}
	\end{definicionTupla}

	    \subsubsection*{Invariante de Representaci\'on}
	    Las condiciones del invariante de representaci\'on se pueden resumir en las siguientes:
    \begin{itemize}
     \item Los tama\~nos de los arreglos dimensionables son iguales a $cota$.
     \item $pos\_libre$ es menor o igual a $cota$.
     \item Los elementos de $posiciones$ son n\'umeros naturales menores a $pos\_libre$ o son exactamente iguales a $cota$.
     \item Si un elemento de $posiciones$ es un natural menor a la $pos\_libre$, no existe otro elemento en el arreglo menor a $pos\_libre$ que tenga el mismo valor.
     \item Los elementos del $heap$ cuya posici\'on es menor a $m.pos\_libre$ son n\'umeros naturales menores a la cota.
     \item El i-\'esimo elemento de $repeticiones$ es igual a 0 sii. el i-\'esimo elemento de $posiciones$ es igual a la cota.
     \item $heap$ cumple que para todo natural $i$ menor a la cota, si $i$ es menor que $pos\_libre$ entonces:
     \begin{itemize}
      \item Si $(2*i+1) < pos\_libre$, entonces $prioridad(i) < prioridad(2*i+1)$ y
      \item si $(2*i+2) < pos\_libre$, entonces $prioridad(i) < prioridad(2*i+2)$,
      \item donde $prioridad(j) =  repeticiones[j] * cota - j$.
     \end{itemize}
     \item $cardinal$ es igual a la sumatoria de los elementos de $repeticiones$.
     \item $elementos$ es un conjunto tal que $e$ pertenece a $elementos$ sii. $repeticiones[e] \neq 0$.
    \end{itemize}

    \tadOperacion{Rep}{estM}{bool}{}
    \tadAxioma{Rep(e)}{true $\Leftrightarrow$ $(tam(m.repeticiones) \igobs tam(m.posiciones) \igobs tam(m.heap) \igobs m.cota) \land$\\
    \indent 	$(m.pos\_libre \le m.cota) \land$\\
    \indent 	$(\forall i: nat,\ i < m.cota)(m.posiciones[i] < m.pos\_libre \lor m.posiciones[i] \igobs m.cota) \land $\\
    \indent 	$(\forall i,j: nat,\ i < m.cota \land j < m.cota)((m.posiciones[i] < pos\_libre \land m.posiciones[j] < pos\_libre)\Rightarrow $\\
    \indent\indent 	$m.posiciones[i] \neq m.posiciones[j]) \land$\\
    \indent	$(\forall i: nat,\ i < m.pos\_libre)(m.heap[i] < m.cota) \land$\\
    \indent	$(\forall i: nat,\ i < m.cota)(m.repeticiones[i] \igobs 0 \Leftrightarrow m.posiciones[i] \igobs m.cota) \land$\\
    \indent	$(\forall i: nat,\ i < m.pos_libre)( ((2*i+1) < pos\_libre \Rightarrow prioridad(i) < repeticiones[2*i+1] \times m.cota - 2*i+1) \land$\\
    \indent				    $((2*i+2) < pos\_libre \Rightarrow prioridad(i) < repeticiones[2*i+2] \times m.cota - 2*i+2)) \land$\\
    \indent	$m.cardinal \igobs sumatoria(m.repeticiones) \land$\\
    \indent 	$e \in m.elementos \Leftrightarrow m.repeticiones[e] \neq 0)$
    }\

    \tadOperacion{Sumatoria}{arreglo\_dimensionable(nat)}{nat}{}
    \tadAxioma{Sumatoria(a)}{Sumatoria(m,0)}
    \tadOperacion{SumatoriaR}{arreglo\_dimensionable(nat), nat}{nat}{}
    \tadAxioma{SumatoriaR(a,i)}{
				\IF $i \igobs tam(a)$ THEN
    				  0
    				ELSE
    				  a[i] + SumatoriaR(a, i + 1)
    				FI}

	    \subsubsection*{Funci\'on de Abstracci\'on}
    \tadOperacion{Abs}{estM}{multconj(nat)}{}
    $(\forall m: estM) Abs(m) = c: multiconj(nat) | (\forall n: nat) ((n < tam(m.repeticiones) \land \#(n, c) \igobs m.repeticiones[n]) \lor $\\
    \indent 						$\#(n, c) \igobs 0)$

	
  	\subsection{Algoritmos}

	      \subsubsection*{Observadores}
	      % Cardinal(m) → nat O(1)
	      % res <- m.cardinal
	      \begin{codebox}
	       \encabezadoFuncion{Cardinal}{\parametro{in}{m}{estM}}{nat}\\
		\li $res \gets m.cardinal$
	      \end{codebox}

	      %Cota(multiconj) $\rightarrow$ nat\\

	      \subsubsection*{Generadores}
	      % MultiConjAcotadoVacio(cota) O(n), tal que n es la cantidad de elementos distintos posibles
	      % m.repeticiones <- CrearArreglo(cota)
	      % m.posiciones <- CrearArreglo(cota)
	      % m.heap <- CrearArreglo(cota)
	      % m.cota <- cota
	      % m.pos_libre <- 0
	      % m.cardinal <- 0
	      % m.elementos <- Vacio(0, cota - 1)
	      % for i=0 to m.cota
	      % 	m.repeticiones[i] <- 0
	      % 	m.posiciones[i] <- cota //cota es una posición inválida que sirve para indicar que el elemento no se encuentra en el conjunto
	      % 
	      \begin{codebox}
	       \encabezadoFuncion{iMultiConjAcotadoVacio}{\parametro{in}{cota}{nat}}{estM}\\
		\li $res.repeticiones \gets$ \proc{CrearArreglo}($cota$)
		\li $res.posiciones \gets$ \proc{CrearArreglo}($cota$)
		\li $res.heap\gets$ \proc{CrearArreglo}($cota$)
		\li $res.cota\gets$ $cota$
		\li $res.pos\_libre \gets 0$
		\li $res.cardinal \gets 0$
		\li $res.elementos \gets$ \proc{Vac\'io}$(0, cota - 1)$
		\li \For $i \gets 0 \To cota - 1$
		\li \Do
			$res.repeticiones[i] \gets 0$
		\li	$res.posiciones[i] \gets cota$
		    \End
		\end{codebox}

 \proc{MultiConjAcotadoVacio} tiene complejidad \complejidad{$O$}{$n$}, donde n es la cantidad de elementos distintos posibles. 
 Esto es as\'i porque esta cantidad es igual a $cota$ y las complejidades de creaci\'on de los arreglos y el conjunto de elementos 
 son \complejidad{$O$}{$cota$}. 
 Adem\'as, el ciclo del for es \complejidad{$O$}{$1$} y se ejecuta $cota$ veces.

	      % Agregar(m, elemento, cantidad) O(log n) (elemento ¡Cota(m), o sea que los elementos van entre 0 y Cota(m)-1)
	      % {supone que m.pos_libre < m.cota y que elemento es menor a la cota}
	      % IF m.repeticiones[elemento] = 0 THEN
	      % 	m.heap[m.pos_libre] <- elemento
	      % 	m.posiciones[elemento] = m.pos_libre
	      % 	m.pos_libre = m.pos_libre +1
	      % 	m.repeticiones[elemento] <- m.repeticiones[elemento] + cantidad
	      % 	subir(m, m.posiciones[elemento])
	      % 	Agregar(m.elementos, elemento)
	      % ELSE
	      % 	m.repeticiones[elemento] <- m.repeticiones[elemento] + cantidad
	      % 	bajar(m, m.posiciones[elemento])
	      % END
	      % m.cardinal <- m.cardinal + cantidad
	      % 
	      \begin{codebox}
	       \encabezadoFuncion{iAgregar}{\parametro{in/out}{m}{estM}, \parametro{in}{elemento}{nat}, \parametro{in}{cantidad}{nat}}{}\\
		\li \If $m.repeticiones[elemento] \isequal 0$ 
		\li \Then
			$m.heap[m.pos\_libre] \gets elemento$
		\li	$m.posiciones[elemento] \gets m.pos\_libre$
		\li	$m.pos\_libre \gets m.pos\_libre + 1$
		\li	$m.repeticiones[elemento] \gets m.repeticiones[elemento] + cantidad$
		\li 	\proc{Subir}($m, m.posiciones[elemento]$)
		\li	\proc{Agregar}($m.elementos, elemento$)
		\li \Else
		\li		$m.repeticiones[elemento] \gets m.repeticiones[elemento] + cantidad$
		\li	\proc{Bajar}(m, m.posiciones[elemento])
		    \End
		\li $m.cardinal \gets m.cardinal + cantidad$
	      \end{codebox}

\proc{Agregar} es \complejidad{$O$}{$\log(n)$}, donde n es la cantidad de elementos distintos en el multiconjunto. 
Esto es as\'i porque, obviando las operaciones que son \complejidad{$O$}{1} tenemos \proc{Agregar}, de conjunto 
acotado de naturales, que es \complejidad{$O$}{1} y las operaciones auxiliares \proc{Subir} y \proc{Bajar}, 
ambas con complejidad \complejidad{$O$}{$\log(n)$}.
	      
	      \subsubsection*{Operaciones}
	      
	      % Quitar(m, elemento, cantidad) O(log n) donde n es la cantidad de elementos distintos
	      % (supongo elemento < cota)
	      % IF m.repeticiones[elemento] > 0 //si el elemento está en el multiconjunto al menos una vez, si no no me gasto
	      % 	IF cantidad <= m.repeticiones[elemento] THEN
	      % 		m.cardinal <- m.cardinal - cantidad
	      % 		m.repeticiones[i] <- m.repeticiones[i] - cantidad
	      % 	ELSE
	      % 		m.cardinal <- m.cardinal - m.repeticiones[elemento]
	      % 		m.repeticiones[i] <- 0
	      % 	END
	      % 	subir(m, m.posiciones[elemento])
	      % 	IF m.repeticiones[elemento] = 0 THEN //si el número de repeticiones es 0 va a quedar en la raiz así que lo elimino
	      % 		EliminarRaiz(m)
	      % 		Eliminar(m.elementos,elemento)
	      % 	END
	      % END
	      % 
	      \begin{codebox}
	       \encabezadoFuncion{iQuitar}{\parametro{in/out}{m}{estM}, \parametro{in}{elemento}{nat}, \parametro{in}{cantidad}{nat}}{}\\
		\li \If $elemento < m.cota \land m.repeticiones[elemento] > 0$ 
		\li \Then
			\If $cantidad \le m.repeticiones[elemento]$
		\li 	\Then
			    $m.cardinal \gets m.cardinal - cantidad$
		\li	    $m.repeticiones[i] \gets m.repeticiones[i] - cantidad$
		\li	\Else    
		\li	    $m.cardinal \gets m.cardinal - m.repeticiones[elemento]$
		\li	    $m.repeticiones[i] \gets 0$
			\End
		\li	\proc{Subir}($m, m.posiciones[elemento]$)
		\li 	\If $m.repeticiones[elemento] \isequal 0$
		\li	\Then
			    \proc{EliminarRaiz}($m$)
		\li	    \proc{Eliminar}($m.elementos, elemento$)
			\End
		    \End
	      \end{codebox}
\proc{Quitar} es \complejidad{$O$}{$\log(n)$}, donde n es la cantidad de elementos distintos en el multiconjunto. 
Esto es as\'i porque, obviando las operaciones que son \complejidad{$O$}{1} tenemos \proc{Eliminar}, de conjunto 
acotado de naturales, que es \complejidad{$O$}{1} y las operaciones auxiliares \proc{Subir} y \proc{EliminarRaiz}, 
ambas con complejidad \complejidad{$O$}{$\log(n)$}.

	      % Pertenece(m, elemento) → bool O(1)
	      % res <- m.repeticiones[elemento] > 0
	      \begin{codebox}
	       \encabezadoFuncion{iPertenece}{\parametro{in}{m}{estM}}{bool}\\
		\li $res \gets m.repeticiones[elemento] > 0$
	      \end{codebox}

	      % Cardinal(m) → nat O(1)
	      % res <- m.cardinal
	      \begin{codebox}
	       \encabezadoFuncion{iCardinal}{\parametro{in}{m}{estM}}{nat}\\
		\li $res \gets m.cardinal$
	      \end{codebox}

	      % Minimo(m) → nat (del jugador) O(1)
	      % res <- m.heap[0]
	      \begin{codebox}
	       \encabezadoFuncion{iMinimo}{\parametro{in}{m}{estM}}{nat}\\
		\li $res \gets m.heap[0]$
	      \end{codebox}

	      % Conj(m) → conj(nat) O(1) (devuelve los elementos (e) tal que #(m, e) ¿0, en un conjunto)
	      % res <- m.elementos
	      \begin{codebox}
	       \encabezadoFuncion{iConj}{\parametro{in}{m}{estM}}{conj(nat)}\\
		\li $res \gets m.elementos$
	      \end{codebox}
\proc{Conj} es \complejidad{$O$}{1} porque devuelve una referencia constante del conjunto de elementos distintos del multiconjunto.

	      % CantDistintos(m) → nat O(1) (es el cardinal del conjunto anterior)
	      % res <- Cardinal(m.elementos)
	      \begin{codebox}
	       \encabezadoFuncion{iCantDistintos}{\parametro{in}{m}{estM}}{nat}\\
		\li $res \gets Cardinal(m.elementos)$
	      \end{codebox}
	
	      \subsubsection*{Operaciones auxiliares no exportadas}
	      % EliminarRaiz(m) (es O(log(cota))) 
	      % 	m.heap[0] <- m.heap[m.pos_libre - 1]
	      % 	m.pos_libre <- m.pos_libre - 1;
	      % 	m.posiciones[m.pos_libre] <- m.cota
	      % 	bajar(m, 0)
	      \begin{codebox}
	       \encabezadoFuncion{EliminarRaiz}{\parametro{in}{m}{estM}}{}\\
		\li	$m.heap[0] \gets m.heap[m.pos_libre - 1]$
	        \li	$m.pos_libre \gets m.pos_libre - 1$
		\li	$m.posiciones[m.pos_libre] \gets m.cota$
	        \li	\proc{Bajar}($m, 0$)
	      \end{codebox}
\proc{EliminarRaiz} es \complejidad{$O$}{$\log(n)$}, donde n es la cantidad de elementos distintos en el multiconjunto. 
Esto es as\'i porque la \'unica operaci\'on que no es \complejidad{$O$}{1} es \proc{Bajar}, cuya complejidad es \complejidad{$O$}{$\log(n)$}.

	      % subir(m, pos) (sube un elemento del heap hasta restablecer el invariante, es O(log(pos)) ) 
	      % i <- pos
	      % WHILE (i != 0) && (prioridad(m.heap(i)) < prioridad(m.heap(padre(i))))
	      % 	p <- padre(m,i)
	      % 	//intercambio posiciones
	      % 	temp <- m.posiciones[m.heap[i]]
	      % 	m.posiciones[m.heap[i]] <- m.posiciones[m.heap[p]]
	      % 	m.posiciones[m.heap[p]] <- temp
	      % 	//intercambio valores en el heap
	      % 	temp <- m.heap[i]	
	      % 	m.heap[i] <- m.heap[p]
	      % 	m.heap[p] <- temp
	      % 	i <- p
	      \begin{codebox}
	       \encabezadoFuncion{Subir}{\parametro{in/out}{m}{estM}, \parametro{in}{pos}{}}{}\\
		\li	$i \gets pos$
		\li 	\While $(i \neq 0) \land ($\proc{Prioridad}($m.heap[i]$) $< prioridad(m.heap[$\proc{Padre}($i$)$]))$
		\li	\Do
			    $p \gets$ \proc{Padre}($m,i$)
		\li	\Comment intercambio posiciones
		\li	$temp \gets m.posiciones[m.heap[i]]$
		\li	$m.posiciones[m.heap[i]] \gets m.posiciones[m.heap[p]]$
		\li	$m.posiciones[m.heap[p]] \gets temp$
		\li	\Comment intercambio valores en el heap
		\li	$temp \gets m.heap[i]$
		\li	$m.heap[i] \gets m.heap[p]$
		\li	$m.heap[p] \gets temp$
	        \li	$i \gets p$
	      \end{codebox}
\proc{Subir} es \complejidad{$O$}{$\log(n)$} porque en el peor caso, se debe subir un elemento que est\'a en el \'ultimo 
nivel del heap hasta la raiz. Esto implica hacer $\log(n)$ intercambios \complejidad{$O$}{1}, siendo n la cantidad de elementos 
en el heap, y coincidiendo este valor conla cantidad de elementos distintos en el multiconjunto.

	      % prioridad(m, elemento) 
	      % (en primer lugar influye la cantidad de repeticiones, y en segundo lugar el número del elemento)
	      % res<- m.repeticiones[elemento] * cota - elemento
	      \begin{codebox}
	       \encabezadoFuncion{Prioridad}{\parametro{in}{m}{estM}, \parametro{in}{elemento}{nat}}{}\\
		\li	$res \gets m.repeticiones[elemento] \times cota - elemento$
	      \end{codebox}

	      % padre(m, i) (devuelve el padre del nodo i en el heap del multiconjunto)
	      % res <- floor((i-1)/2)
	      \begin{codebox}
	       \encabezadoFuncion{Padre}{\parametro{in}{m}{estM}, \parametro{in}{i}{nat}}{}\\
		\li	$res \gets \lfloor(i-1)/2)\rfloor$
	      \end{codebox}

	      % bajar(m,pos) (baja un elemento del heap hasta restablecer el invariante)
	      % i <- pos
	      % izq <- 2*i+1
	      % der <- 2*i+2  
	      % WHILE i < floor(m.pos_libre/2) &&  ( (izq < m.pos_libre && prioridad(i) > prioridad(izq)) || (der < m.pos_libre && prioridad(i) > prioridad(der)) )
	      % 	IF (prioridad(izq) < prioridad(der)) THEN	
	      % 		h <- izq
	      % 	ELSE
	      % 		h <- der
	      % 	END
	      % 	//intercambio posiciones
	      % 	temp <- m.posiciones[m.heap[i]]
	      % 	m.posiciones[m.heap[i]] <- m.posiciones[m.heap[h]]
	      % 	m.posiciones[m.heap[h]] <- temp
	      % 	//intercambio valores en el heap
	      % 	temp <- m.heap[i]	
	      % 	m.heap[i] <- m.heap[h]
	      % 	m.heap[h] <- temp
	      % 	i <- h
	      % 	izq <- 2*i+1
	      % 	der <- 2*i+2  
	      \begin{codebox}
	       \encabezadoFuncion{Bajar}{\parametro{in/out}{m}{estM}, \parametro{in}{pos}{}}{}\\
		\li	$i \gets pos$
		\li	$izq \gets 2 \times i + 1$
		\li	$der \gets 2 \times i + 2$
		\li 	\While ($i < \lfloor(m.pos\_libre/2)\rfloor$) $\land$\\ ($izq < m.pos\_libre \land$ \proc{Prioridad}($i$) $>$ \proc{Prioridad}($izq$)) $\lor$ ($der < m.pos\_libre \land$ \proc{Prioridad}($i$) $>$ \proc{Prioridad}($der$)) )
		\li	\Do
			    \If \proc{Prioridad}($izq$)$<$\proc{Prioridad}($der$))	
		\li 	    \Then
				$h \gets izq$
		\li	    \Else
		\li		$h \gets der$
			    \End
		\li	\Comment intercambio posiciones
		\li	$temp \gets m.posiciones[m.heap[i]]$
		\li	$m.posiciones[m.heap[i]] \gets m.posiciones[m.heap[h]]$
		\li	$m.posiciones[m.heap[h]] \gets temp$
		\li	\Comment intercambio valores en el heap
		\li	$temp \gets m.heap[i]$
		\li	$m.heap[i] \gets m.heap[h]$
		\li	$m.heap[h] \gets temp$
	        \li	$i \gets h$
		\li 	$izq \gets 2 \times i + 1$
		\li 	$der \gets 2 \times i + 2$
	      \end{codebox}
\proc{Bajar} es \complejidad{$O$}{$\log(n)$} porque en el peor caso, se debe bajar un elemento desde la ra\'iz hasta el \'ultimo 
nivel del heap. Esto implica hacer $\log(n)$ intercambios \complejidad{$O$}{1}, siendo n la cantidad de elementos 
en el heap, y coincidiendo este valor con la cantidad de elementos distintos en el nto.
	
	      
  	\subsection{Servicios Utilizados}
\begin{itemize}
 \item \emph{ConjuntoAcotado Nat}, de elementos $Nat$. Cuenta con operaciones \proc{Vacio} de complejidad \complejidad{$\Theta$}{$r-l$}, 
\proc{Agregar} de complejidad \complejidad{$\Theta$}{1}, \proc{Eliminar} de complejidad \complejidad{$\Theta$}{1}, y \proc{Cardinal} de 
complejidad \complejidad{$\Theta$}{1}.
 \item \proc{CrearArreglo} es \complejidad{$O$}{$n$}, donde $n$ es el tama\~no del arreglo.
\end{itemize}
